/**
 * 常用工具函数
 */

export * from './request'
export * from './storage'
export * from './env'

/**
 * 深拷贝对象
 * @param obj 要拷贝的对象
 */
export function deepClone<T>(obj: T): T {
  if (obj === null || typeof obj !== 'object') {
    return obj;
  }

  if (obj instanceof Date) {
    return new Date(obj.getTime()) as unknown as T;
  }

  if (obj instanceof Array) {
    return obj.map(item => deepClone(item)) as unknown as T;
  }

  if (obj instanceof Object) {
    const copy = {} as Record<string, unknown>;
    Object.keys(obj).forEach(key => {
      copy[key] = deepClone((obj as Record<string, unknown>)[key]);
    });
    return copy as T;
  }

  return obj;
}

/**
 * 防抖函数
 * @param fn 要执行的函数
 * @param delay 延迟时间
 */
export function debounce<T extends (...args: any[]) => any>(fn: T, delay = 300): (...args: Parameters<T>) => void {
  let timer: ReturnType<typeof setTimeout> | null = null;

  return function(this: unknown, ...args: Parameters<T>) {
    if (timer) {
      clearTimeout(timer);
    }

    timer = setTimeout(() => {
      fn.apply(this, args);
      timer = null;
    }, delay);
  };
}

/**
 * 节流函数
 * @param fn 要执行的函数
 * @param threshold 阈值
 */
export function throttle<T extends (...args: any[]) => any>(fn: T, threshold = 300): (...args: Parameters<T>) => void {
  let last: number;
  let timer: ReturnType<typeof setTimeout> | null = null;

  return function(this: unknown, ...args: Parameters<T>) {
    const now = Date.now();

    if (last && now < last + threshold) {
      if (timer) {
        clearTimeout(timer);
      }

      timer = setTimeout(() => {
        last = now;
        fn.apply(this, args);
        timer = null;
      }, threshold);
    } else {
      last = now;
      fn.apply(this, args);
    }
  };
}

/**
 * 格式化日期
 * @param date 日期对象或时间戳
 * @param format 格式化模板，如 YYYY-MM-DD HH:mm:ss
 */
export function formatDate(date: Date | number | string, format = 'YYYY-MM-DD HH:mm:ss'): string {
  const d = new Date(date);

  const formatMap: Record<string, number> = {
    'YYYY': d.getFullYear(),
    'MM': d.getMonth() + 1,
    'DD': d.getDate(),
    'HH': d.getHours(),
    'mm': d.getMinutes(),
    'ss': d.getSeconds()
  };

  return format.replace(/(YYYY|MM|DD|HH|mm|ss)/g, (match) => {
    const value = formatMap[match];
    return match === 'YYYY' ? String(value) : value < 10 ? `0${value}` : String(value);
  });
}

/**
 * 判断对象是否为空
 * @param obj 要判断的对象
 */
export function isEmpty(obj: unknown): boolean {
  if (obj === null || obj === undefined) {
    return true
  }

  if (typeof obj === 'string' || obj instanceof Array) {
    return obj.length === 0
  }

  if (obj instanceof Map || obj instanceof Set) {
    return obj.size === 0
  }

  if (obj instanceof Object) {
    return Object.keys(obj).length === 0
  }

  return false
}

/**
 * 获取URL参数
 * @param url URL字符串
 */
export function getUrlParams(url: string): Record<string, string> {
  const params: Record<string, string> = {}
  const queryString = url.split('?')[1]

  if (!queryString) return params

  const paramPairs = queryString.split('&')

  for (const pair of paramPairs) {
    const [key, value] = pair.split('=')
    if (key) {
      params[decodeURIComponent(key)] = decodeURIComponent(value || '')
    }
  }

  return params
}

/**
 * 生成UUID
 */
export function generateUUID(): string {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
    const r = (Math.random() * 16) | 0
    const v = c === 'x' ? r : (r & 0x3) | 0x8
    return v.toString(16)
  })
}

/**
 * 延迟函数
 * @param ms 延迟毫秒数
 */
export function delay(ms: number): Promise<void> {
  return new Promise(resolve => setTimeout(resolve, ms))
}
